#include <vector>
#include <string>
class Wave
{
public:
    Wave ( double f0 = 440.0, double s0 = 44100.0, const std::string& n0 = "") : freq ( f0 ), sampleRate ( s0 ), name(n0) { }

    double GetFreq() const
    {
        return freq;
    }
    virtual std::vector<double> MakeWaveTable
    ( int repeat, double rangeMax = 1.0, double rangeMin = 0.0 ) const = 0;
    double GetSampleRate() const
    {
        return sampleRate;
    }
    std::string GetName() const { return name;}
    void SetName(const std::string& n0) { name=n0;}
protected:
    double freq;
    double sampleRate;
    std::string name;
};

class Sine : public Wave
{
public:
    Sine ( double f0 = 440.0, double s0 = 44100.0, const std::string& n0 = "" ) : Wave ( f0, s0, n0 ) { }
    virtual std::vector<double> MakeWaveTable
    ( int repeat, double rangeMax = 1.0, double rangeMin = 0.0 ) const;
protected:
};

class AlignedSine : public Sine
{
public:
    AlignedSine ( double f0 = 440.0, double s0 = 44100.0, bool autoAlign = true, double thres0 = 0.1 , const std::string& n0="" )
            : Sine ( f0, s0, n0 ) , loop ( 1 ) , thres ( thres0 )
    {
        if ( autoAlign ) Align();
    }
    int GetLoop() const
    {
        return loop;
    }
    double GetThres() const
    {
        return thres;
    }
    bool Align ( int minLoop = 1, int maxLoop = 0 , bool strict = true);
private:
    //int FindProperLoops(int minLoop, int maxLoop);

    int loop;
    double thres;
};
